package com.open.validator.impl;

import com.open.validator.NotBlankExt;
import org.apache.commons.beanutils.BeanUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.lang.reflect.InvocationTargetException;
import java.util.Arrays;

/**
 * @author: system
 * @Date: 2024/4/19 15:10
 * @Version: V1.0
 * @description: desc:
 */

public class NotBlankExtValidator implements ConstraintValidator<NotBlankExt, Object> {

    private static final Logger log = LoggerFactory.getLogger(NotBlankExtValidator.class);

    private String[] values;
    private String field;
    private String depField;
    private String[] depValue;

    @Override
    public void initialize(NotBlankExt parameters) {
        values = parameters.value();
        field = parameters.field();
        depField = parameters.depField();
        depValue = parameters.depValue();
    }

    /**
     * field,depField,depValue三个属性其一为null值，不进行校验；<br>
     * 依赖字段为null值，不进行校验；<br>
     * depValue不等于依赖字段的值，不进行校验
     */
    @Override
    public boolean isValid(Object object, ConstraintValidatorContext context) {

        try {

            if (object == null || field == null || depField == null || depValue == null) {
                return true;
            }

            String checkedValue = BeanUtils.getProperty(object, field);

            String requiredValue = BeanUtils.getProperty(object, depField);
            if (requiredValue == null) {
                return true;
            }

            if (depValue.length == 0 || Arrays.asList(depValue).contains(requiredValue)) {

                // 未配置value时，执行@NotBlank注解功能
                if (values.length == 0) {

                    if (checkedValue == null) {
                        return false;
                    }

                    return checkedValue.toString().trim().length() > 0;
                }

                if (Arrays.asList(values).contains(checkedValue)) {

                    return true;
                } else {

                    return false;
                }

            } else {
                return true;
            }

        } catch (IllegalAccessException e) {
            log.error("Accessor method is not available for class : {}, exception : {}", object.getClass().getName(),
                    e);
            return false;
        } catch (NoSuchMethodException e) {
            log.error("Field or method is not present on class : {}, exception : {}", object.getClass().getName(), e);
            return false;
        } catch (InvocationTargetException e) {
            log.error("An exception occurred while accessing class : {}, exception : {}", object.getClass().getName(),
                    e);
            return false;
        }

    }

}
